package com.seckill.goods.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seckill.act.feign.ActivityFeign;
import com.seckill.act.feign.SkuActFeign;
import com.seckill.act.pojo.Activity;
import com.seckill.act.pojo.SkuAct;
import com.seckill.framework.mybatisplus.WrapperParse;
import com.seckill.goods.mapper.SkuMapper;
import com.seckill.goods.pojo.Sku;
import com.seckill.goods.service.SkuService;
import com.seckill.util.Result;
import com.seckill.util.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品表 服务实现类
 * </p>
 *
 * @author 作者
 * @since 2022-03-04
 */
@Service
@Slf4j
public class SkuServiceImpl extends ServiceImpl<SkuMapper, Sku> implements SkuService {

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private SkuActFeign skuActFeign;

    @Autowired
    private ActivityFeign activityFeign;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /***
     * 库存递减
     * @param id
     * @param count
     * @return
     */
    @Override
    public int dcount(String id, Integer count) {
        //1.调用Dao实现递减
        int dcount = skuMapper.dcount(id, count);
        //2.递减失败
        if (dcount == 0) {
            //查询
            Sku sku = skuMapper.selectById(id);
            //2.1递减失败原因->库存不足->405
            if (sku.getSeckillNum() < count) {
                return ResultCode.DECOUNT_NUM.getCode();
            } else if (sku.getIslock() == 2) {
                //2.2递减失败原因->变成热点->205
                return ResultCode.DECOUNT_HOT.getCode();
            }
            return 0;
        }
        return ResultCode.DECOUNT_OK.getCode();
    }

    /****
     * 热点商品隔离
     * @param id
     */
    @Override
    public void hotIsolation(String id) {
        //1.数据库该商品进行锁定操作
        Sku sku = new Sku();
        sku.setIslock(2);   //锁定
        //执行锁定
        QueryWrapper<Sku> wrapper = WrapperParse.simpleColumns("islock,id", 1, id);
        int count = skuMapper.update(sku, wrapper);

        //2.锁定成功了，则把商品存入到Redis缓存进行隔离
        if (count > 0) {
            String key = "SKU_" + id;
            Sku currentSku = skuMapper.selectById(id);

            //2.数据合并
            Map<String, Object> dataMap = new HashMap<String, Object>();
            dataMap.put("num", currentSku.getSeckillNum());
            //存储商品信息
            Map<String, Object> info = new HashMap<String, Object>();
            info.put("id", id);
            info.put("price", currentSku.getSeckillPrice());
            info.put("name", currentSku.getName());
            dataMap.put("info", info);
            //1.2次操作合并成1次
            redisTemplate.boundHashOps(key).putAll(dataMap);
        }
    }

    /***
     * 查询总数
     * @return
     */
    @Override
    public Integer counts() {
        return skuMapper.counts();
    }

    /****
     * 分页列表查询
     * @param page
     * @param size
     * @return
     */
    @Override
    public List<Sku> list(Integer page, Integer size) {
        //1.分页-PageHelper
        IPage<Sku> iPage = new Page<Sku>(page, size);

        //2.分页集合查询
        IPage<Sku> pageInfo = skuMapper.selectPage(iPage, null);
        return pageInfo.getRecords();
    }

    /**
     * Sku条件+分页查询
     *
     * @param sku  查询条件
     * @param page 页码
     * @param size 页大小
     * @return 分页结果
     */
    @Override
    public Page<Sku> findPage(Sku sku, int page, int size) {
        //分页
        IPage<Sku> iPage = new Page<Sku>(page, size);
        //搜索条件构建
        QueryWrapper<Sku> wrapper = WrapperParse.simple(sku);
        //执行搜索
        IPage<Sku> pageInfo = skuMapper.selectPage(iPage, wrapper);
        return (Page<Sku>) pageInfo;
    }

    /**
     * Sku分页查询
     *
     * @param page
     * @param size
     * @return
     */
    @Override
    public Page<Sku> findPage(int page, int size) {
        //静态分页
        IPage<Sku> iPage = new Page<Sku>(page, size);
        //分页查询
        return (Page<Sku>) skuMapper.selectPage(iPage, null);
    }

    /**
     * Sku条件查询
     *
     * @param sku
     * @return
     */
    @Override
    public List<Sku> findList(Sku sku) {
        //构建查询条件
        QueryWrapper<Sku> wrapper = WrapperParse.simple(sku);
        //根据构建的条件查询数据
        return skuMapper.selectList(wrapper);
    }


    /**
     * 删除
     *
     * @param id
     */
    @Override
    public void delete(String id) {
        //查询商品信息
        Sku currentsku = skuMapper.selectById(id);

        if (currentsku != null) {
            //查询活动信息
            Result<Activity> actResult = activityFeign.findByBgtime(currentsku.getSeckillBegin());
            Activity currentActivity = actResult.getData();

            //skuMapper.deleteByPrimaryKey(id);
            Sku sku = new Sku();
            sku.setId(id);
            sku.setStatus(1); //非秒杀商品
            sku.setIslock(1);   //未锁定
            int count = skuMapper.updateById(sku);
            if (count > 0) {
                //移除关联
                skuActFeign.delByASId(currentActivity.getId(), currentsku.getId());
            }
        }
    }

    /**
     * 修改Sku
     *
     * @param sku
     */
    @Override
    public void update(Sku sku) {
        skuMapper.updateById(sku);
    }

    /**
     * 增加Sku
     *
     * @param sku
     */
    @Override
    public void add(Sku sku) {
        skuMapper.insert(sku);
    }

    /**
     * 根据ID查询Sku
     *
     * @param id
     * @return
     */
    @Override
    public Sku findById(String id) {
        String json = redisTemplate.opsForValue().get("SKU::" + id);
        if (!StringUtils.hasText(json)) {
            log.info("缓存中不存在商品信息 , 从数据库查询-----");
            Sku sku = skuMapper.selectById(id);
            json = JSON.toJSONString(sku);
            redisTemplate.opsForValue().set("SKU::" + id, json);
        }

        return JSON.parseObject(json, Sku.class);
        //return skuMapper.selectById(id);
    }

    /**
     * 查询Sku全部数据
     *
     * @return
     */
    @Override
    public List<Sku> findAll() {
        return skuMapper.selectList(null);
    }

    /***
     * 锁定商品
     * @param id
     */
    @Override
    public void lock(String id) {
        skuMapper.lock(id);
    }

    /***
     * 解锁商品
     * @param id
     */
    @Override
    public void unlock(String id) {
        skuMapper.unlock(id);
    }

    /***
     * 根据活动ID查询
     * @param id
     * @param page
     * @param size
     * @return
     */
    @Override
    public Page<Sku> findSkuByActivityId(String id, Integer page, Integer size) {
        //分页
        Result<Page<SkuAct>> skuActResult = skuActFeign.findPageByActId(id, page, size);
        Page<SkuAct> pageInfo = skuActResult.getData();

        //查询
        List<String> skuIds = pageInfo.getRecords().stream().map(SkuAct::getSkuId).collect(Collectors.toList());

        if (skuIds != null && skuIds.size() > 0) {
            QueryWrapper<Sku> wrapper = new QueryWrapper<Sku>();
            wrapper.in("id", skuIds);
            List<Sku> skuList = skuMapper.selectList(wrapper);
            Page<Sku> skuPage = new Page<Sku>(page, size, pageInfo.getTotal());
            skuPage.setRecords(skuList);
            return skuPage;
        }

        Page<Sku> skuPage = new Page<Sku>();
        skuPage.setSize(10);
        skuPage.setPages(0);
        skuPage.setTotal(0);
        return skuPage;
    }

    /***
     * 提取所有ID
     * @param skuList
     * @return
     */
    public List<String> getIds(List<Sku> skuList) {
        List<String> ids = new ArrayList<String>();
        for (Sku sku : skuList) {
            ids.add(sku.getId());
        }
        return ids;
    }

    /***
     * 归零设置
     * @param id
     */
    @Override
    public void zero(String id) {
        Sku sku = new Sku();
        sku.setId(id);
        sku.setSeckillNum(0);
        skuMapper.updateById(sku);
    }

    /***
     * 商品更新成非秒杀商品，未锁定商品
     */
    @Override
    public void modifySku() {
        //修改状态
        skuMapper.modifySku();
    }

    @Override
    public List<Sku> findTop(String id) {
        //查询对应的商品信息
        Result<List<String>> idsResult = skuActFeign.findSkuById(id);
        QueryWrapper<Sku> wrapper = WrapperParse.simpleIn("id", idsResult.getData());
        return skuMapper.selectList(wrapper);
    }

    @Override
    public List<Sku> seckillPrice(List<String> ids) {
        QueryWrapper<Sku> wrapper = WrapperParse.simpleIn("id", ids);
        List<Sku> skus = skuMapper.selectList(wrapper);
        return skus;
    }


    /**
     * 剩余的秒杀商品数量
     *
     * @param id
     * @return
     */
    @Override
    public Object skuSeckillCount(String id) {
        return Result.ok(skuMapper.selectSeckillCount(id));
    }
}
